home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-MIPS / SYSTEM.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  5KB  |  224 lines

  1. /* $Id: system.h,v 1.8 1998/07/20 17:52:21 ralf Exp $
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
  8.  * Modified further for R[236]000 by Paul M. Antoine, 1996
  9.  */
  10. #ifndef __ASM_MIPS_SYSTEM_H
  11. #define __ASM_MIPS_SYSTEM_H
  12.  
  13. #include <asm/sgidefs.h>
  14. #include <linux/kernel.h>
  15.  
  16. extern __inline__ void
  17. __sti(void)
  18. {
  19.     __asm__ __volatile__(
  20.         ".set\tnoreorder\n\t"
  21.         ".set\tnoat\n\t"
  22.         "mfc0\t$1,$12\n\t"
  23.         "ori\t$1,0x1f\n\t"
  24.         "xori\t$1,0x1e\n\t"
  25.         "mtc0\t$1,$12\n\t"
  26.         ".set\tat\n\t"
  27.         ".set\treorder"
  28.         : /* no outputs */
  29.         : /* no inputs */
  30.         : "$1", "memory");
  31. }
  32.  
  33. /*
  34.  * For cli() we have to insert nops to make shure that the new value
  35.  * has actually arrived in the status register before the end of this
  36.  * macro.
  37.  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  38.  * no nops at all.
  39.  */
  40. extern __inline__ void
  41. __cli(void)
  42. {
  43.     __asm__ __volatile__(
  44.         ".set\tnoreorder\n\t"
  45.         ".set\tnoat\n\t"
  46.         "mfc0\t$1,$12\n\t"
  47.         "ori\t$1,1\n\t"
  48.         "xori\t$1,1\n\t"
  49.         "mtc0\t$1,$12\n\t"
  50.         "nop\n\t"
  51.         "nop\n\t"
  52.         "nop\n\t"
  53.         ".set\tat\n\t"
  54.         ".set\treorder"
  55.         : /* no outputs */
  56.         : /* no inputs */
  57.         : "$1", "memory");
  58. }
  59.  
  60. #define __save_flags(x)                  \
  61. __asm__ __volatile__(                    \
  62.     ".set\tnoreorder\n\t"            \
  63.     "mfc0\t%0,$12\n\t"               \
  64.     ".set\treorder"                  \
  65.     : "=r" (x)                       \
  66.     : /* no inputs */                \
  67.     : "memory")
  68.  
  69. #define __save_and_cli(x)                \
  70. __asm__ __volatile__(                    \
  71.     ".set\tnoreorder\n\t"            \
  72.     ".set\tnoat\n\t"                 \
  73.     "mfc0\t%0,$12\n\t"               \
  74.     "ori\t$1,%0,1\n\t"               \
  75.     "xori\t$1,1\n\t"                 \
  76.     "mtc0\t$1,$12\n\t"               \
  77.     "nop\n\t"                        \
  78.     "nop\n\t"                        \
  79.     "nop\n\t"                        \
  80.     ".set\tat\n\t"                   \
  81.     ".set\treorder"                  \
  82.     : "=r" (x)                       \
  83.     : /* no inputs */                \
  84.     : "$1", "memory")
  85.  
  86. extern void __inline__
  87. __restore_flags(int flags)
  88. {
  89.     __asm__ __volatile__(
  90.         ".set\tnoreorder\n\t"
  91.         "mtc0\t%0,$12\n\t"
  92.         "nop\n\t"
  93.         "nop\n\t"
  94.         "nop\n\t"
  95.         ".set\treorder"
  96.         : /* no output */
  97.         : "r" (flags)
  98.         : "memory");
  99. }
  100.  
  101. /*
  102.  * Non-SMP versions ...
  103.  */
  104. #define sti() __sti()
  105. #define cli() __cli()
  106. #define save_flags(x) __save_flags(x)
  107. #define save_and_cli(x) __save_and_cli(x)
  108. #define restore_flags(x) __restore_flags(x)
  109.  
  110. #define mb()                        \
  111. __asm__ __volatile__(                    \
  112.     "# prevent instructions being moved around\n\t"    \
  113.     ".set\tnoreorder\n\t"                \
  114.     "# 8 nops to fool the R4400 pipeline\n\t"    \
  115.     "nop;nop;nop;nop;nop;nop;nop;nop\n\t"        \
  116.     ".set\treorder"                    \
  117.     : /* no output */                \
  118.     : /* no input */                \
  119.     : "memory")
  120.  
  121. #if !defined (_LANGUAGE_ASSEMBLY)
  122. /*
  123.  * switch_to(n) should switch tasks to task nr n, first
  124.  * checking that n isn't the current task, in which case it does nothing.
  125.  */
  126. extern asmlinkage void (*resume)(void *tsk);
  127. #endif /* !defined (_LANGUAGE_ASSEMBLY) */
  128.  
  129. #define switch_to(prev,next) \
  130. do { \
  131.     resume(next); \
  132. } while(0)
  133.  
  134. /*
  135.  * For 32 and 64 bit operands we can take advantage of ll and sc.
  136.  * FIXME: This doesn't work for R3000 machines.
  137.  */
  138. extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
  139. {
  140. #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
  141.     (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
  142.     unsigned long dummy;
  143.  
  144.     __asm__ __volatile__(
  145.         ".set\tnoreorder\n\t"
  146.         ".set\tnoat\n\t"
  147.         "ll\t%0,(%1)\n"
  148.         "1:\tmove\t$1,%2\n\t"
  149.         "sc\t$1,(%1)\n\t"
  150.         "beqzl\t$1,1b\n\t"
  151.         "ll\t%0,(%1)\n\t"
  152.         ".set\tat\n\t"
  153.         ".set\treorder"
  154.         : "=r" (val), "=r" (m), "=r" (dummy)
  155.         : "1" (m), "2" (val)
  156.         : "memory");
  157. #else
  158.     unsigned long flags, retval;
  159.  
  160.     save_flags(flags);
  161.     cli();
  162.     retval = *m;
  163.     *m = val;
  164.     restore_flags(flags);
  165.  
  166. #endif /* Processor-dependent optimization */
  167.     return val;
  168. }
  169.  
  170. /*
  171.  * Only used for 64 bit kernel.
  172.  */
  173. extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
  174. {
  175.     unsigned long dummy;
  176.  
  177.     __asm__ __volatile__(
  178.         ".set\tnoreorder\n\t"
  179.         ".set\tnoat\n\t"
  180.         "lld\t%0,(%1)\n"
  181.         "1:\tmove\t$1,%2\n\t"
  182.         "scd\t$1,(%1)\n\t"
  183.         "beqzl\t$1,1b\n\t"
  184.         "ll\t%0,(%1)\n\t"
  185.         ".set\tat\n\t"
  186.         ".set\treorder"
  187.         : "=r" (val), "=r" (m), "=r" (dummy)
  188.         : "1" (m), "2" (val)
  189.         : "memory");
  190.  
  191.     return val;
  192. }
  193.  
  194. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  195. #define tas(ptr) (xchg((ptr),1))
  196.  
  197. /*
  198.  * This function doesn't exist, so you'll get a linker error
  199.  * if something tries to do an invalid xchg().
  200.  *
  201.  * This only works if the compiler isn't horribly bad at optimizing.
  202.  * gcc-2.5.8 reportedly can't handle this, but I define that one to
  203.  * be dead anyway.
  204.  */
  205. extern void __xchg_called_with_bad_pointer(void);
  206.  
  207. static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  208. {
  209.     switch (size) {
  210.         case 4:
  211.             return xchg_u32(ptr, x);
  212. #if defined(__mips64)
  213.         case 8:
  214.             return xchg_u64(ptr, x);
  215. #endif
  216.     }
  217.     __xchg_called_with_bad_pointer();
  218.     return x;
  219. }
  220.  
  221. extern void set_except_vector(int n, void *addr);
  222.  
  223. #endif /* __ASM_MIPS_SYSTEM_H */
  224.